package org.jsola.contract.service.impl;

import com.timevale.esign.sdk.tech.v3.client.ServiceClient;
import lombok.extern.slf4j.Slf4j;
import org.jsola.contract.common.ClientHelper;
import org.jsola.contract.common.ESignHelper;
import org.jsola.contract.constant.ContractConstants;
import org.jsola.contract.core.ContractProperties;
import org.jsola.contract.entity.ContractCredentialDO;
import org.jsola.contract.entity.ContractCredentialSiteDO;
import org.jsola.contract.service.IContractCredentialService;
import org.jsola.contract.service.IContractCredentialSiteService;
import org.jsola.exception.ParamException;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.jsola.user.constant.UserConstants.DEFAULT_SITE_ID;

/**
 * @author JanusMix
 */
@Component
@Slf4j
public class ThirdSignClientFactory {

    @Autowired
    private IContractCredentialSiteService contractCredentialSiteService;

    @Autowired
    private IContractCredentialService contractCredentialService;

    @Autowired
    private ContractProperties contractProperties;

    private static final Map<String, ESignHelper> CLIENT_MAP = new HashMap<>(16);

    @PostConstruct
    public void init() {
        try {
            log.info("开始加载e签宝配置");
            if (!contractProperties.getUseDbConfig()) {
                log.info("使用配置文件的配置");
                if (contractProperties.getESign() == null) {
                    log.error("未配置e签宝配置文件，初始化结束");
                    return;
                }
                //注册客户端
                ESignHelper eSignHelper = this.createESignHelper(contractProperties.getESign().getProjectId(),
                        contractProperties.getESign().getSecret(),
                        contractProperties.getESign().getApiUrl());
                CLIENT_MAP.put(DEFAULT_SITE_ID, eSignHelper);
                return;
            }
            log.info("使用数据库的配置");
            //获取所有e签宝配置
            List<ContractCredentialDO> contractCredentialList = contractCredentialService.selectAll();
            if (CollectionUtils.isEmpty(contractCredentialList)) {
                log.error("数据库未找到e签宝配置文件，初始化结束");
                return;
            }
            for (ContractCredentialDO contractCredentialDO : contractCredentialList) {
                //注册客户端
                ESignHelper eSignHelper = this.createESignHelper(contractCredentialDO.getProjectId(), contractCredentialDO.getSecret(), contractCredentialDO.getApiUrl());
                CLIENT_MAP.put(contractCredentialDO.getSiteId(), eSignHelper);
            }
        } catch (Exception e) {
            log.error("注册e签宝失败，失败原因：{}", e.toString());
        }
    }

    /**
     * 获取租户的e签宝客户端
     *
     * @param tokenUser 当前登录用户
     * @return e签宝客户端
     */
    public synchronized ESignHelper getClient(TokenUser tokenUser) {
        ESignHelper eSignHelper;
        if (!contractProperties.getUseDbConfig()) {
            log.info("使用默认e签宝配置");
            eSignHelper = CLIENT_MAP.get(DEFAULT_SITE_ID);
        } else {
            String siteId = tokenUser.getSiteId();
            ParamException.notNull(siteId, "租户不正确");
            log.info("使用租户" + siteId + "的配置");
            eSignHelper = CLIENT_MAP.get(siteId);
            if (eSignHelper == null) {
                ContractCredentialSiteDO contractCredentialSiteDO = contractCredentialSiteService.selectSiteCredential(siteId);
                ParamException.notNull(contractCredentialSiteDO, "当前租户未开通电子合同");
                ContractCredentialDO contractCredentialDO = contractCredentialService.selectDOById(contractCredentialSiteDO.getContractCredentialId(), siteId);
                ParamException.notNull(contractCredentialDO, "电子合同账号不存在或已删除");
                //注册客户端
                eSignHelper = this.createESignHelper(contractCredentialDO.getProjectId(), contractCredentialDO.getSecret(), contractCredentialDO.getApiUrl());
                CLIENT_MAP.put(contractCredentialDO.getSiteId(), eSignHelper);
            }
        }
        return eSignHelper;
    }

    private ESignHelper createESignHelper(String projectId, String secret, String apiUrl) {
        //注册客户端
        ClientHelper.registClient(projectId, secret, apiUrl);
        ServiceClient serviceClient = ClientHelper.getServiceClient(projectId);
        return new ESignHelper(serviceClient);
    }

}
